#include <iostream>
#include <string>
#include <regex>

int main()
{
    std::string str = "GET /baidu/login?12324 HTTP/1.1";
    std::smatch matches;
    std::regex e("(GET|POST|HEAD|PUT|DELETE) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\r\n|\n)?");
    //(GET|POST|HEAD|PUT|DELETE) 表示匹配并提取其中任意一个字符串；
    //([^?]*) 其中[^?]表示匹配非?字符， *表示匹配0次或者多次；([^?]*)表示提取非？字符0次或者多次，直到遇到？字符停止；
    //.*其中 . 表示匹配除了换行符外的任意一个字符， *表示匹配0次或者多次
    //由于？在正则表达式中有特殊含义，所以要表示字符串中的？需要进行转义，在字符串中要表示原始的？应该写 \\?
    //\\?(.*) 其中\\？表示原始的？字符，(.*)表示提取？之后的任意字符0次或者多次，直到遇到空格
    //(HTTP/1\\.[01]) 表示匹配以HTTP\1.开始的字符串，其中\\. 表示 . 字符是因为点在正则表达式中有特殊含义，需要进行转义；
    // (?:\r\n|\n)? 其中(?:...)表示匹配某个字符串，但是不提取；不规范请求行后面可能会出现没有\r\n,也没有\n的情况，使用？可以匹配0次或者一次；
    // 遇到不规范的请求行后也可以成功匹配并完成提取；
    // (?:\\?(.*))? 表示以？开始的字符串不要，需要提取？之后的字符串；最后的？表示匹配前面的模式0次或者1次；
    bool ret = std::regex_match(str, matches, e);
    if(!ret)
    {
        return -1;
    }
    for(const auto& a : matches)
    {
        std::cout << a << std::endl;
    }
    return 0;
}
